'use strict'
const http = require('http');
//require在程序运行时，可以动态的导入模块
let html = `
    <!DOCTYPE html>
    <html>
        <head>
            <title>First HTTP</title>
        </head>
        <body>
            你好。
        </body>
    </html>`;

let routerTable = {
    '/':async(ctx) => {
        response.setHeader('content-type','text/html;charset=utf-8');
        response.end(html);
    },
    '/test':async(ctx) => {
        let status = parseInt(Math.random() * 200) + 199;
        response.statusCode = status;
        response.end('test end');
    },
    '/data':async(request,response) => {
        let bufferList = [];
        let bufferLength = 0;
        request.on('data',chunk => {
            bufferLength += chunk.length;
            bufferList.push(chunk);
        })

        let bodyData = null;
        request.on('end',() => {
            if(bufferList.length>0){
                bodyData = Buffer.concat(bufferList,bufferLength);
                bufferList = [];
            }
            if(bodyData){
                response.end(bodyData);
            }else{
                response.end();
            }
        })
    }
}

http.createServer(async (request,response) => {
    let rm = routerTable[request.method];
    let usplit = request.url.split('?');
    let pathname = usplit[0];
    let querystring = usplit[1] || '';
    if(!rm || !rm [ pathname ]){
        response.statusCode = 404;
        response.end('page not found');
        return ;
    }
    //ctx 是 context 的缩写，意为请求上下文，就是一个打包了各种数据和方法的对象
    let ctx = {
        method:request.method,
        path:pathname,
        search:querystring,
        headers:request.headers,
        response:response,
        end:(data,encoding = 'utf8') => {
            response.end(data,encoding)
        },
        write:(data,encoding = 'utf8') => {
            response.write(data,encoding)
        },
        totalLength:0,
        rawBody:null,
        bufferList:[]
    }

    await new Promise((rv,rj) => {
        if('PD',indexOf(request.method[0]) >= 0){
            request.on('data',chunk => {
                ctx.bufferList.push(chunk);
                totalList += chunk.length;
            })
        }else{
            request.on('data',data => {
                response.statusCode = 400;
                response.end('bad request',() => {
                    request.destroy();
                });
            })
        }
    })

    let resolved = false;
    request.on('end',() => {
        resolved = true;
        rv();
    })
    request.on('close',() => {
        (!resolved) && rv();
    })

    if(!response.writable || response.writableEnded){
        return 
    }

    rm[pathname](ctx)
}).listen(3456); 

/*各种格式的对照情况
    .jpg .jpeg -> image/jpeg
    .png -> image/png
    .gif -> image/gif
    .ico -> image/x-icon
    .txt -> text/plain
    .json -> text/json 或 application/json
    .xml -> text/xml 或 application/xml
 */
//setHeader构造协议头，以包的形式一起发送出去
//text/html服务器告诉浏览器，这是一个html文件，以Html文件的形式解析
//charset=utf-8告诉浏览器文字的格式是utf8的形式，这样可以翻译出中文